/*
 * JFrameDropUI.java
 *
 * Created on 14.12.2009, 21:07:17
 */
package dndExample;

import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.event.KeyEvent;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author bernd
 * Simple Drag and Drop GUI-App
 * You can Drag and Drop Files, Directories and Browser-URLs to the Drop-Target
 * Notice, that Opera does not support drag and drop [besides to the windows-Dsktop]
 * But Dropping URLs works corectly with Firefox,IE and GoogleChrome.
 * Copy/Paste is correctly detected for all 
 */
public class JFrameDropUI extends javax.swing.JFrame implements DropTargetListener {

    /** Creates new form JFrameDropUI */
    public JFrameDropUI() {
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jFrame1 = new javax.swing.JFrame();
        drop_jTF = new javax.swing.JTextField();
        echo_jsp = new javax.swing.JScrollPane();
        echoDroppedpAndPasted_jta = new javax.swing.JTextArea();
        dropTarget_jl = new javax.swing.JLabel();
        sysMsg_jsp = new javax.swing.JScrollPane();
        sys_msg_jta = new javax.swing.JTextArea();
        echo_jl = new javax.swing.JLabel();
        sys_msg_jl = new javax.swing.JLabel();

        jFrame1.setBackground(new java.awt.Color(241, 15, 15));

        javax.swing.GroupLayout jFrame1Layout = new javax.swing.GroupLayout(jFrame1.getContentPane());
        jFrame1.getContentPane().setLayout(jFrame1Layout);
        jFrame1Layout.setHorizontalGroup(
            jFrame1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 400, Short.MAX_VALUE)
        );
        jFrame1Layout.setVerticalGroup(
            jFrame1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 300, Short.MAX_VALUE)
        );

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Drop and Paste Demo");
        setAlwaysOnTop(true);
        setBackground(new java.awt.Color(142, 226, 25));
        setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR));
        setFont(new java.awt.Font("Verdana", 0, 10)); // NOI18N
        setForeground(java.awt.Color.white);
        setName("drop_and_paste_jf"); // NOI18N

        drop_jTF.setEditable(false);
        drop_jTF.setBackground(new java.awt.Color(255, 255, 204));
        drop_jTF.setFont(new java.awt.Font("Verdana", 0, 10)); // NOI18N
        drop_jTF.setHorizontalAlignment(javax.swing.JTextField.CENTER);
        drop_jTF.setText("(drop it here)");
        drop_jTF.setToolTipText("(drop something here)");
        drop_jTF.setDragEnabled(true);
        drop_jTF.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                drop_jTFKeyPressed(evt);
            }
        });

        echoDroppedpAndPasted_jta.setBackground(javax.swing.UIManager.getDefaults().getColor("TextArea.disabledBackground"));
        echoDroppedpAndPasted_jta.setColumns(20);
        echoDroppedpAndPasted_jta.setEditable(false);
        echoDroppedpAndPasted_jta.setFont(new java.awt.Font("Verdana", 0, 10)); // NOI18N
        echoDroppedpAndPasted_jta.setLineWrap(true);
        echoDroppedpAndPasted_jta.setRows(5);
        echoDroppedpAndPasted_jta.setToolTipText("(dropped texts)");
        echoDroppedpAndPasted_jta.setWrapStyleWord(true);
        echoDroppedpAndPasted_jta.setEnabled(false);
        echo_jsp.setViewportView(echoDroppedpAndPasted_jta);

        dropTarget_jl.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
        dropTarget_jl.setText("Drag and Drop or Paste either URL, File or Directory");

        sys_msg_jta.setEditable(false);
        sys_msg_jta.setBackground(javax.swing.UIManager.getDefaults().getColor("TextArea.disabledBackground"));
        sys_msg_jta.setColumns(20);
        sys_msg_jta.setFont(new java.awt.Font("Courier New", 0, 10)); // NOI18N
        sys_msg_jta.setLineWrap(true);
        sys_msg_jta.setRows(5);
        sys_msg_jta.setWrapStyleWord(true);
        sys_msg_jta.setEnabled(false);
        sysMsg_jsp.setViewportView(sys_msg_jta);

        echo_jl.setText("Last successfully dropped / pasted clipboard entry");

        sys_msg_jl.setText("Last System Message: Error, Info, ...");

        DropTarget dropTarget = new DropTarget(drop_jTF, this);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                    .addComponent(echo_jsp)
                    .addComponent(drop_jTF)
                    .addComponent(sysMsg_jsp)
                    .addComponent(dropTarget_jl)
                    .addComponent(sys_msg_jl)
                    .addComponent(echo_jl))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(dropTarget_jl)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(drop_jTF, javax.swing.GroupLayout.PREFERRED_SIZE, 73, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(echo_jl)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(echo_jsp, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(3, 3, 3)
                .addComponent(sys_msg_jl)
                .addGap(1, 1, 1)
                .addComponent(sysMsg_jsp, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void drop_jTFKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_drop_jTFKeyPressed
        if (evt.getKeyCode() == KeyEvent.VK_V && evt.isControlDown()) {
            //CTRL + V was pressed!

            dropResult.clear();
            sys_msg_jta.setText("");
            echoDroppedpAndPasted_jta.setText("");

            Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
            Transferable tr = c.getContents(null);
            String urlStr = null;

            try {
                if (tr.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
                    List droppedFileNameList = (List) tr.getTransferData(DataFlavor.javaFileListFlavor);

                    // drop accepted - process droppedFileNameList now ...
                    dropResult.setFileList(droppedFileNameList);
                    echoDroppedpAndPasted_jta.setText(droppedFileNameList.toString());

                } else if (tr.isDataFlavorSupported(JFrameDropUI.urlFlavor)) {
                    URL url = (URL) tr.getTransferData(urlFlavor);

                    // drop accepted - process dropped URL now ...
                    dropResult.setUrl(url);
                    echoDroppedpAndPasted_jta.setText(dropResult.getUrl().toString());
                } else if ((tr.isDataFlavorSupported(DataFlavor.stringFlavor))) {

                    urlStr = (String) tr.getTransferData(DataFlavor.stringFlavor);
                    URL url = new URL(urlStr);

                    // drop accepted - process dropped URL now ...
                    dropResult.setUrl(url);
                    echoDroppedpAndPasted_jta.setText(dropResult.getUrl().toString());
                } else {
                    //unsupported flavor
                    sys_msg_jta.setText("drop_jTFKeyPressed: unsupported flavor!");
                }
            } catch (MalformedURLException e) {
                sys_msg_jta.setText("Bad URL: " + urlStr);
            } catch (Exception ex) {
                Logger.getLogger(JFrameDropUI.class.getName()).log(Level.SEVERE, null, ex);
                sys_msg_jta.setText("Exception in drop_jTFKeyPressed: " + ex.getMessage());
            } finally {
                //notifies DragSource that the drop transfer(s) was successfully completed.
                //dtde.dropComplete(true);
            }

        }
        return;
    }//GEN-LAST:event_drop_jTFKeyPressed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel dropTarget_jl;
    private javax.swing.JTextField drop_jTF;
    private javax.swing.JTextArea echoDroppedpAndPasted_jta;
    private javax.swing.JLabel echo_jl;
    private javax.swing.JScrollPane echo_jsp;
    private javax.swing.JFrame jFrame1;
    private javax.swing.JScrollPane sysMsg_jsp;
    private javax.swing.JLabel sys_msg_jl;
    private javax.swing.JTextArea sys_msg_jta;
    // End of variables declaration//GEN-END:variables

    public void dragEnter(DropTargetDragEvent dtde) {
        sys_msg_jta.setText("");
        echoDroppedpAndPasted_jta.setText("");
        boolean flavorSupported =
                dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor) ||
                dtde.isDataFlavorSupported(JFrameDropUI.urlFlavor);
        //dragSupported = dragSupported || dtde.isDataFlavorSupported(DataFlavor.stringFlavor);
        if (!flavorSupported) {
            dtde.rejectDrag();
            sys_msg_jta.setText("dragEnter: unsupported flavor!");
        }
        return;
    }

    public void dragOver(DropTargetDragEvent dtde) {
        //throw new UnsupportedOperationException("Not supported yet.");
    }

    public void dropActionChanged(DropTargetDragEvent dtde) {
        //throw new UnsupportedOperationException("Not supported yet.");
    }

    public void dragExit(DropTargetEvent dte) {
        //throw new UnsupportedOperationException("Not supported yet.");
    }

    public void drop(DropTargetDropEvent dtde) {

        dropResult.clear();
        sys_msg_jta.setText("");
        echoDroppedpAndPasted_jta.setText("");
        Transferable tr = dtde.getTransferable();
        dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);

        try {
            if (tr.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
                List droppedFileNameList =
                        (List) tr.getTransferData(DataFlavor.javaFileListFlavor);

                // drop accepted - process droppedFileNameList now ...
                dropResult.setFileList(droppedFileNameList);
                echoDroppedpAndPasted_jta.setText(dropResult.getFileList().toString());

            } else if (tr.isDataFlavorSupported(JFrameDropUI.urlFlavor)) {
                URL url = (URL) tr.getTransferData(urlFlavor);

                // drop accepted - process dropped URL now ...
                dropResult.setUrl(url);
                echoDroppedpAndPasted_jta.setText(dropResult.getUrl().toString());
            } else {
                //unsupported flavor
                sys_msg_jta.setText("drop: unsupported flavor!");
                dtde.rejectDrop();
            }
        } catch (Exception ex) {
            Logger.getLogger(JFrameDropUI.class.getName()).log(Level.SEVERE, null, ex);
            dtde.rejectDrop();
            sys_msg_jta.setText("Exception in drop: " + ex.getMessage());
        } finally {
            //notifies DragSource that the drop transfer(s) was successfully completed.
            dtde.dropComplete(true);
        }
    }
    private DropResult dropResult = new DropResult();
    static DataFlavor urlFlavor;

    static {

        try {
            urlFlavor =
                    new DataFlavor("application/x-java-url; class=java.net.URL");
        } catch (ClassNotFoundException cnfe) {
            cnfe.printStackTrace();
        }
    }
}
